package JUC.AQS;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author CKC
 * @DateTime 2021/4/18 20:59
 */
public class AQSDemo {
    public static void main(String[] args) throws InterruptedException {

        //测试LockSupport 能否对 Condition 里面等待的线程进行唤醒  ————>可以唤醒 但是唤醒的线程还是会执行 LockSupport.park() 继续阻塞

        ReentrantLock reentrantLock = new ReentrantLock();
        Condition condition = reentrantLock.newCondition();
        Thread thread = new Thread(() -> {
            try {
                reentrantLock.lock();
                //Thread.sleep(1000);
                condition.await();
                System.out.println("-----------");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                reentrantLock.unlock();
            }
        });
        thread.start();
        new Thread(() -> {
            //Thread.sleep(1000);
            LockSupport.unpark(thread);
            System.out.println("---");
        }).start();
    }

    public static void demo() {
        ReentrantLock lock = new ReentrantLock(false);

        //带入一个银行办理业务的案例来模拟我们AQS如何进行线程的管理和通知唤醒机制
        //三个线程模拟三个银行网点，受理窗口办理业务

        //A 第一个顾客，此时手里窗口没有任何人，A可以直接办理
        new Thread(() -> {
            lock.lock();
            try {

                System.out.println("-----------------A");
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            } finally {
                lock.unlock();
            }
        }, "A").start();

        //第二个顾客，第二个线程，---》由于受理业务的窗口只有一个（只能一个线程持有锁），此时B只能等待。进入候客区
        new Thread(() -> {
            lock.lock();
            try {

                System.out.println("-----------------Son thread come in");

            } finally {
                lock.unlock();
            }
        }, "B").start();


        //第3个顾客，第3个线程，---》由于受理业务的窗口只有一个（只能一个线程持有锁），此时C只能等待。进入候客区
        new Thread(() -> {
            lock.lock();
            try {
                System.out.println("-----------------C thread come in");
            } finally {
                lock.unlock();
            }
        }, "C").start();
    }
}
